﻿using AutoMapper;
using DFGK_WMS.Context;
using DFGK_WMS.IRepository;
using DFGK_WMS.Model.Models;
using DFGK_WMS.Model.NoNet;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using NPOI.Util;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DFGK_WMS.Repository
{
    public class TMaterialRepository : BaseRepository<TMaterial>, ITMaterialRepository
    {
        private readonly SqliteContext sqlite;
        public TMaterialRepository(DFGK_DB context, IMapper mapper, SqliteContext sqlite) : base(context, mapper)
        {
            this.sqlite = sqlite;
        }

        /// <summary>
        /// 添加物料
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool AddMaterial(TMaterial m)
        {
            try
            {
                var obj = Context.TMaterials.AsNoTracking().FirstOrDefault(x => x.Code == m.Code);
                if (obj != null)
                {
                    return false;
                }
                m.CreateDate = DateTime.Now;
                m.ModifyDate = DateTime.Now;
                m.TypeId = 2;
                m.TypeName = "成品";
                m.TypeCode = "EndProduct";
                m.MaterialCategoryCode = m.MaterialCategoryCode;
                m.UnitName = m.UnitName;
                m.InventoriesTypeStatus = 1;
                Context.TMaterials.Add(m);
                return Context.SaveChanges() > 0;
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 删除物料
        /// </summary>
        /// <param name="mid"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool DelMaterial(int mid)
        {
            var mobj = Context.TMaterials.Find(mid);

            if (mobj != null)
            {
                Context.TMaterials.Remove(mobj);
            }
            return Context.SaveChanges() > 0;
        }

        /// <summary>
        /// 根据主键获取对象信息
        /// </summary>
        /// <param name="mid"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public TMaterial GetMaterialById(int mid)
        {
            return Context.TMaterials.Find(mid);
        }

        /// <summary>
        /// 生成一个物料号
        /// </summary>
        /// <param name="mid"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public string GetMaterialCode(int mid)
        {
            string mcode = "";
            //查找该分类是否存在
            var obj = Context.TMaterialCategories.Find(mid);
            string mvalue = "";
            if (obj != null)
            {
                mcode += obj.Code + ",";
                //mvalue = obj.Id.ToString();
                int? j = obj.ParentId;
                //无限循环查找该对象是否为父级
                for (int i = 0; ; i++)
                {
                    //不是父级进行查询否则退出循环
                    if (obj.ParentId != 0)
                    {
                        //查找该对象
                        var objs = Context.TMaterialCategories.AsNoTracking().FirstOrDefault(x => x.Id == j);
                        if (objs != null)
                        {
                            //如果存在拿出编码
                            mcode += objs.Code + ",";
                            j = objs.ParentId;
                        }
                        else
                            break;
                    }
                    else
                        break;
                }

                string result = "";
                for (int i = 1; ; i++)
                {
                    if (i < 10)
                    {
                        result = mvalue + "0000" + i;
                    }
                    else if (i < 100)
                    {
                        result = mvalue + "000" + i;
                    }
                    else if (i < 1000)
                    {
                        result = mvalue + "00" + i;
                    }
                    else if (i < 10000)
                    {
                        result = mvalue + "0" + i;
                    }
                    else
                    {
                        result = i.ToString();
                    }
                    string inputStr = result + "," + mcode + "XZBD";
                    string[] elements = inputStr.Split(",");
                    Array.Reverse(elements);
                    result = string.Join("", elements);
                    var mobj = Context.TMaterials.AsNoTracking().FirstOrDefault(x => x.Code == result);
                    if (mobj != null)
                    {
                        continue;
                    }
                    else
                        break;
                }

                return result;
            }
            return null;
        }

        /// <summary>
        /// 物料列表显示
        /// </summary>
        /// <param name="mname"></param>
        /// <param name="materialcategoryid"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <param name="totalCount"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<TMaterial> GetMaterialList(int? materialCategoryId, string? materialcategoryName, string? materialName, decimal? startPrice, decimal? endPrice, int pageIndex, int pageSize, out int totalCount)
        {
            var query = Context.TMaterials.AsNoTracking().AsQueryable();

            if (materialCategoryId != null)
            {
                query = query.Where(x => x.MaterialCategoryId == materialCategoryId);
            }

            if (!string.IsNullOrEmpty(materialcategoryName))
            {
                query = query.Where(x => x.MaterialCategoryName.Contains(materialcategoryName));
            }

            if (!string.IsNullOrEmpty(materialName))
            {
                query = query.Where(x => x.Name.Contains(materialName));
            }

            if (startPrice != null && endPrice != null)
            {
                query = query.Where(x => x.Price >= startPrice && x.Price <= endPrice);
            }

            totalCount = query.Count();

            var materialList = query.OrderByDescending(x => x.CreateDate)
                                     .Skip((pageIndex - 1) * pageSize)
                                     .Take(pageSize)
                                     .ToList();

            return materialList;
        }

        /// <summary>
        /// 修改物料
        /// </summary>
        /// <param name="m"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool UpdMaterial(TMaterial m)
        {
            var list = Context.TMaterials.AsNoTracking().FirstOrDefault(x => x.Id != m.Id && x.Code == m.Code);

            if (list != null)
            {
                return false;
            }

            m.ModifyDate = DateTime.Now;
            Context.TMaterials.Update(m);
            return Context.SaveChanges() > 0;
        }

        /// <summary>
        /// 导出物料管理
        /// </summary>
        /// <returns></returns>
        public List<TMaterial> GetTMaterialExcel()
        {
            try
            {
                return Context.TMaterials.AsQueryable().ToList();
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 获取全部物料
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public List<TMaterial> GetAllMaterialList()
        {
            try
            {
                return Context.TMaterial.AsQueryable().ToList();
            }
            catch (Exception)
            {
                throw;
            }
        }

        /// <summary>
        /// 批量添加物料
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool AddMaterialList(List<TMaterial> list)
        {
            if (list.Count <= 0)
            {
                return false;
            }
            Context.TMaterial.AddRange(list);
            return Context.SaveChanges() > 0;
        }

        /// <summary>
        /// 一键同步器材数据
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool AddMaterialListForSqlite(List<TMaterial> list)
        {
            using var tran = Context.Database.BeginTransaction();
            try
            {
                //创建表（如果不存在）
                bool aa = sqlite.Database.EnsureCreated();
                // 设置连接字符串
                string connectionString = "Data Source=/root/WMS/PC-Service/wwwroot/file/chat.db";

                // 创建连接对象
                using (var connection = new SqliteConnection(connectionString))
                {
                    // 打开连接
                    connection.Open();

                    // 创建SQL命令对象
                    using (var command = connection.CreateCommand())
                    {
                        // 设置清空缓存的SQL语句
                        command.CommandText = "PRAGMA cache_size=0;";

                        // 执行SQL命令
                        command.ExecuteNonQuery();

                        Console.WriteLine("Cache cleared.");
                    }

                    // 关闭连接
                    connection.Close();
                }
                var MaterialListRemove = sqlite.MaterialTable.AsQueryable().ToList();
                sqlite.MaterialTable.RemoveRange(MaterialListRemove);
                foreach (var item in list)
                {

                    MaterialTable MaterialList = new MaterialTable()
                    {
                        MaterialCategoryId = item.MaterialCategoryId,
                        MaterialCategoryCode = item.MaterialCategoryCode,
                        MaterialCategoryName = item.MaterialCategoryName,
                        MaterialId = item.Id,
                        MaterialName = item.Name,
                        MaterialCode = item.Code,
                        QualityState = item.QualityState,
                        InventoryQty = GetInventoryByMaterialCode(item.Code) == null ? null : GetInventoryByMaterialCode(item.Code).AvailableQty,
                        Position = GetInventoryByMaterialCode(item.Code) == null ? null : GetInventoryByMaterialCode(item.Code).LocationName,
                        UnitId = item.UnitId,
                        UnitName = item.UnitName,

                    };
                    sqlite.MaterialTable.Add(MaterialList);
                }
                if (sqlite.SaveChanges() <= 0)
                {
                    tran.Rollback();
                    return false;
                }
                tran.Commit();
                return true;
            }
            catch
            {
                tran.Rollback();
                return false;
            }
        }

        public TInventory GetInventoryByMaterialCode(string materialCode)
        {
            try
            {
                var list = Context.TInventories.First(x => x.MaterialCode == materialCode);
                return list;
            }
            catch
            {
                return null;
            }

        }


        public TDictItem GetDictItems(string unitName)
        {
            var dictItem = Context.TDictItems.FirstOrDefault(x => x.ItemName == unitName);
            return dictItem;
        }

        public TMaterialCategory GetCategoryByCode(string code)
        {
            var category = Context.TMaterialCategories.FirstOrDefault(x => x.Code == code);
            return category;
        }

        public TMaterialGroup GetMaterialGroupByName(string name)
        {
            var group = Context.TMaterialGroups.FirstOrDefault(x => x.Name == name);
            return group;
        }

        public bool UpdMaterial(List<TMaterial> list)
        {
            Context.TMaterial.AddRange(list);
            return Context.SaveChanges() > 0;
        }
    }
}